var viewers
import * as Constants from './Constants'
import * as utils from './utils'
import * as echarts from 'echarts'
class MeasureTool {
    constructor(viewer, options = {}) {
        if (viewer && viewer instanceof Cesium.Viewer) {
            // this._drawLayer = new Cesium.CustomDataSource('measureLayer');
            // viewer && viewer.dataSources.add(this._drawLayer);

            this._basePath = options.basePath || '';

            this._viewer = viewer;
            this.viewer = viewer;
            viewers = viewer
            this.entityCollection = []
            this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
            this.label = options.label.value
            this.addDataSource = options.addDataSource

            this.interData = []
            this._entities_billboard = []
            this.positions = []

            // 集结地
            this._positions = []
            this.t = 0.4
            this.floatingPoint = null //标识点
            this._gatheringPlace = null //活动集结地
            this._gatheringPlaceLast = null //最后一个集结地
            this._entities_gatheringPlace = [] //脏数据
            this._gatheringPlaceData = null //用于构造集结地数据
            this.lonLatArr = []


            // 直线箭头
            this.floatPoint = {}
            this.zxjtArr = []
        }
    }

    /***
     * 坐标转换 84转笛卡尔
     *
     * @param {Object} {lng,lat,alt} 地理坐标
     *
     * @return {Object} Cartesian3 三维位置坐标
     */
    transformWGS84ToCartesian(position, alt) {
        if (this._viewer) {
            return position
                ? Cesium.Cartesian3.fromDegrees(
                    position.lng || position.lon,
                    position.lat,
                    (position.alt = alt || position.alt),
                    Cesium.Ellipsoid.WGS84,
                )
                : Cesium.Cartesian3.ZERO;
        }
    }
    /***
     * 坐标数组转换 笛卡尔转84
     *
     * @param {Array} WSG84Arr {lng,lat,alt} 地理坐标数组
     * @param {Number} alt 拔高
     * @return {Array} Cartesian3 三维位置坐标数组
     */
    transformWGS84ArrayToCartesianArray(WSG84Arr, alt) {
        if (this._viewer && WSG84Arr) {
            var $this = this;
            return WSG84Arr
                ? WSG84Arr.map(function (item) {
                    return $this.transformWGS84ToCartesian(item, alt);
                })
                : [];
        }
    }

    /***
     * 坐标转换 笛卡尔转84
     *
     * @param {Object} Cartesian3 三维位置坐标
     *
     * @return {Object} {lng,lat,alt} 地理坐标
     */
    transformCartesianToWGS84(cartesian) {
        if (this._viewer && cartesian) {
            var ellipsoid = Cesium.Ellipsoid.WGS84;
            var cartographic = ellipsoid.cartesianToCartographic(cartesian);
            return {
                lng: Cesium.Math.toDegrees(cartographic.longitude),
                lat: Cesium.Math.toDegrees(cartographic.latitude),
                alt: cartographic.height,
            };
        }
    }

    /***
     * 坐标数组转换 笛卡尔转86
     *
     * @param {Array} cartesianArr 三维位置坐标数组
     *
     * @return {Array} {lng,lat,alt} 地理坐标数组
     */
    transformCartesianArrayToWGS84Array(cartesianArr) {
        if (this._viewer) {
            var $this = this;
            return cartesianArr
                ? cartesianArr.map(function (item) {
                    return $this.transformCartesianToWGS84(item);
                })
                : [];
        }
    }

    /**
     * 84坐标转弧度坐标
     * @param {Object} position wgs84
     * @return {Object} Cartographic 弧度坐标
     *
     */
    transformWGS84ToCartographic(position) {
        return position
            ? Cesium.Cartographic.fromDegrees(position.lng || position.lon, position.lat, position.alt)
            : Cesium.Cartographic.ZERO;
    }

    /**
     * 拾取位置点
     *
     * @param {Object} px 屏幕坐标
     *
     * @return {Object} Cartesian3 三维坐标 getPickRay
     */
    getCatesian3FromPX(px) {
        if (this._viewer && px) {
            var picks = this._viewer.scene.drillPick(px);
            var cartesian = null;
            var isOn3dtiles = false,
                isOnTerrain = false;
            // drillPick
            for (let i in picks) {
                let pick = picks[i];

                if (
                    (pick && pick.primitive instanceof Cesium.Cesium3DTileFeature) ||
                    (pick && pick.primitive instanceof Cesium.Cesium3DTileset) ||
                    (pick && pick.primitive instanceof Cesium.Model)
                ) {
                    //模型上拾取
                    isOn3dtiles = true;
                }
                // 3dtilset
                if (isOn3dtiles) {
                    this._viewer.scene.pick(px); // pick
                    cartesian = this._viewer.scene.pickPosition(px);
                    if (cartesian) {
                        let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
                        if (cartographic.height < 0) cartographic.height = 0;
                        let lon = Cesium.Math.toDegrees(cartographic.longitude),
                            lat = Cesium.Math.toDegrees(cartographic.latitude),
                            height = cartographic.height;
                        cartesian = this.transformWGS84ToCartesian({
                            lng: lon,
                            lat: lat,
                            alt: height,
                        });
                    }
                }
            }
            // 地形
            let boolTerrain = this._viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider;
            // Terrain
            if (!isOn3dtiles && !boolTerrain) {
                var ray = this._viewer.scene.camera.getPickRay(px);
                if (!ray) return null;
                cartesian = this._viewer.scene.globe.pick(ray, this._viewer.scene);
                isOnTerrain = true;
            }
            // 地球
            if (!isOn3dtiles && !isOnTerrain && boolTerrain) {
                cartesian = this._viewer.scene.camera.pickEllipsoid(px, this._viewer.scene.globe.ellipsoid);
            }
            if (cartesian) {
                let position = this.transformCartesianToWGS84(cartesian);
                if (position.alt < 0) {
                    cartesian = this.transformWGS84ToCartesian(position, 0.1);
                }
                return cartesian;
            }
            return false;
        }
    }

    /**
     * 获取84坐标的距离
     * @param {*} positions
     */

    getSpaceDistance(positions) {
        var distance = 0
        for (var i = 0; i < positions.length - 1; i++) {
            var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i])
            var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1])
            /** 根据经纬度计算出距离**/
            var geodesic = new Cesium.EllipsoidGeodesic()
            geodesic.setEndPoints(point1cartographic, point2cartographic)
            var s = geodesic.surfaceDistance
            // 返回两点之间的距离
            s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2))
            distance = distance + s
        }
        console.log(distance);
        return Number(distance.toFixed(2))
    }
    getPositionDistance(positions) {
        let distance = 0;
        for (let i = 0; i < positions.length - 1; i++) {
            let point1cartographic = this.transformWGS84ToCartographic(positions[i]);
            let point2cartographic = this.transformWGS84ToCartographic(positions[i + 1]);
            let geodesic = new Cesium.EllipsoidGeodesic();
            geodesic.setEndPoints(point1cartographic, point2cartographic);
            let s = geodesic.surfaceDistance;
            s = Math.sqrt(
                Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2),
            );
            distance = distance + s;
        }
        // return distance.toFixed(3);
        console.log(distance);
        return Number(distance.toFixed(2))
    }
    /**
     * 计算一组坐标组成多边形的面积
     * @param {*} positions
     */
    getPositionsArea(positions) {
        let result = 0;
        if (positions) {
            let h = 0;
            let ellipsoid = Cesium.Ellipsoid.WGS84;
            positions.push(positions[0]);
            for (let i = 1; i < positions.length; i++) {
                let oel = ellipsoid.cartographicToCartesian(
                    this.transformWGS84ToCartographic(positions[i - 1]),
                );
                let el = ellipsoid.cartographicToCartesian(this.transformWGS84ToCartographic(positions[i]));
                h += oel.x * el.y - el.x * oel.y;
            }
            result = Math.abs(h).toFixed(2);
        }
        return result;
    }
    destroy() {
        if (this.handler) {
            this.handler.destroy()
            this.handler = null
        }
    }

    // 添加点
    addPoint(position) {
        this.entityCollection.push(this.addDataSource.entities.add(new Cesium.Entity({
            position: position,
            point: {
                pixelSize: 10,
                outlineColor: Cesium.Color.BLUE,
                outlineWidth: 5,
                clampToGround: true,
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
            }
        })));
    };

    // 划线
    Straight(positions) {
        this.addDataSource.entities.add(
            new Cesium.Entity({
                polyline: {
                    positions: new Cesium.CallbackProperty(() => positions, false),
                    width: 2,
                    material: Cesium.Color.YELLOW,
                    clampToGround: true,
                }
            })
        )
    }
    // 添加面
    addPolyGon(positions) {
        this.entityCollection.push(this.addDataSource.entities.add(new Cesium.Entity({
            polygon: {
                hierarchy: new Cesium.CallbackProperty(() => {
                    return new Cesium.PolygonHierarchy(positions);
                }, false),
                material: Cesium.Color.RED.withAlpha(0.6),
                classificationType: Cesium.ClassificationType.BOTH // 贴地表和贴模型,如果设置了，这不能使用挤出高度
            }
        })));
    };
    // 距离计算
    distance(point1, point2) {
        var point1cartographic = Cesium.Cartographic.fromCartesian(point1);
        var point2cartographic = Cesium.Cartographic.fromCartesian(point2);
        /**根据经纬度计算出距离**/
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        //console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));
        //返回两点之间的距离
        s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
        return s;
    }

    /**
     * 测距
     * @param {*} options
     */
    drawLineMeasureGraphics(options = {}) {


        if (this._viewer && options) {
            console.log(222);
            this.destroy()
            var label = options.label
            var positions = [],
                _lineEntity = new Cesium.Entity(),
                $this = this,
                lineObj
            // _handlers = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
            this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)
            // left
            this.handler.setInputAction(function (movement) {
                console.log(222);
                var cartesian = $this.getCatesian3FromPX(movement.position);
                if (cartesian && cartesian.x) {
                    if (positions.length == 0) {
                        positions.push(cartesian.clone());
                    }
                    console.log(options);

                    // 添加量测信息点
                    _addInfoPoint(cartesian);
                    positions.push(cartesian);
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            this.handler.setInputAction(function (movement) {
                $this.label.style.display = 'block'
                $this.label.innerHTML = '左键添加点，右键结束测量'
                $this.label.style.left = movement.endPosition.x + 10 + 'px'
                $this.label.style.top = movement.endPosition.y + 15 + 'px'
                var cartesian = $this.getCatesian3FromPX(movement.endPosition);
                if (positions.length >= 2) {
                    if (cartesian && cartesian.x) {

                        positions.pop();
                        positions.push(cartesian);
                    }
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
            // right
            this.handler.setInputAction(function (movement) {
                $this.destroy();

                positions.pop() // 最后一个点无效
                let cartesian = $this.getCatesian3FromPX(movement.position);
                // _addInfoPoint(cartesian);
                console.log($this.transformCartesianArrayToWGS84Array(positions), lineObj);
                if (typeof options.callback === 'function') {

                    options.callback($this.transformCartesianArrayToWGS84Array(positions), lineObj);
                }
                $this.label.style.display = "none"
                // }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

            this.Straight(positions)
            // _lineEntity.polyline = {
            //     width: options.width || 5,
            //     material: options.material || Cesium.Color.BLUE.withAlpha(0.8),
            //     clampToGround: false,
            //     clampToGround: true,
            //     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
            // };
            // _lineEntity.polyline.positions = new Cesium.CallbackProperty(function () {
            //     return positions;
            // }, false);

            lineObj = this.addDataSource.entities.add(_lineEntity);

            //添加坐标点
            function _addInfoPoint(position) {
                var _labelEntity = new Cesium.Entity();
                _labelEntity.position = position;
                _labelEntity.point = {
                    pixelSize: 10,
                    outlineColor: Cesium.Color.BLUE,
                    outlineWidth: 5,
                    clampToGround: true,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                };
                _labelEntity.monitoItems = false
                _labelEntity.label = {
                    text:
                        (
                            $this.getPositionDistance($this.transformCartesianArrayToWGS84Array(positions)) / 1000
                        ).toFixed(4) + '公里',
                    show: true,
                    showBackground: true,
                    font: '14px monospace',
                    horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    pixelOffset: new Cesium.Cartesian2(-10, -10), //left top
                };
                $this.addDataSource.entities.add(_labelEntity);
            }
        }
    }

    /**
     * 测面积
     * @param {*} options
     */
    drawAreaMeasureGraphics(options = {}) {

        var positions = [];
        var clickStatus = false;
        var labelEntity = null;
        var that = this
        this.destroy()

        this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)
        var $this = this
        this.handler.setInputAction((clickEvent) => {
            $this.label.style.display = "block"
            clickStatus = true;
            var cartesian = that.viewer.scene.globe.pick(that.viewer.camera.getPickRay(clickEvent.position), that.viewer.scene);
            // var cartesian = $this.getCatesian3FromPX(clickEvent.position);
            if (!cartesian) {
                return false
            }
            if (positions.length == 0) {
                positions.push(cartesian.clone()); //鼠标左击 添加第1个点
                $this.addPoint(cartesian);

                $this.handler.setInputAction((moveEvent) => {
                    $this.label.style.display = "block"
                    $this.label.style.left = moveEvent.endPosition.x + 10 + 'px'
                    $this.label.style.top = moveEvent.endPosition.y + 15 + 'px'
                    $this.label.innerHTML = '左键添加点，右键结束测量'
                    var movePosition = that.viewer.scene.globe.pick(that.viewer.camera.getPickRay(moveEvent.endPosition), that.viewer.scene);
                    // var movePosition = $this.getCatesian3FromPX(moveEvent.endPosition);
                    if (!movePosition) {
                        return false;
                    }
                    if (positions.length == 1) {
                        positions.push(movePosition);
                        $this.Straight(positions);
                    } else {
                        if (clickStatus) {
                            positions.push(movePosition);
                        } else {
                            positions.pop();
                            positions.push(movePosition);
                        }
                    }
                    if (positions.length >= 3) {
                        // 绘制label
                        if (labelEntity) {
                            this.addDataSource.entities.remove(labelEntity);
                            that.entityCollection.splice(that.entityCollection.indexOf(labelEntity), 1);
                        }

                        var text = "面积：" + getArea(positions);
                        var centerPoint = getCenterOfGravityPoint(positions);
                        labelEntity = addLabel(centerPoint, text);

                        that.entityCollection.push(labelEntity);
                    }
                    clickStatus = false;
                }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);


            } else if (positions.length == 2) {
                if (!cartesian) {
                    return false
                }
                positions.pop();
                positions.push(cartesian.clone()); // 鼠标左击 添加第2个点
                $this.addPoint(cartesian);
                $this.addPolyGon(positions);
                // 右击结束
                $this.handler.setInputAction((clickEvent) => {
                    var clickPosition = that.viewer.scene.globe.pick(that.viewer.camera.getPickRay(clickEvent.position), that.viewer.scene);
                    if (!clickPosition) {
                        return false;
                    }
                    positions.pop();
                    positions.push(clickPosition);
                    positions.push(positions[0]); // 闭合
                    this.addPoint(clickPosition);

                    $this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                    $this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
                    $this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
                    $this.label.style.display = "none"
                }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

            } else if (positions.length >= 3) {
                if (!cartesian) {
                    return false
                }
                positions.pop();
                positions.push(cartesian.clone()); // 鼠标左击 添加第3个点
                $this.addPoint(cartesian);
            }

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        // 添加标签
        function addLabel(position, text) {
            return $this.addDataSource.entities.add(
                new Cesium.Entity({
                    position: position,
                    label: {
                        text: text,
                        font: '14px sans-serif',
                        style: Cesium.LabelStyle.FILL_AND_OUTLINE, //FILL  FILL_AND_OUTLINE OUTLINE
                        fillColor: Cesium.Color.YELLOW,
                        showBackground: true, //指定标签后面背景的可见性
                        backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8), // 背景颜色
                        backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充padding
                        pixelOffset: new Cesium.Cartesian2(0, -25),
                        disableDepthTestDistance: Number.POSITIVE_INFINITY
                    }
                })
            )
        }

        /*方向*/
        function Bearing(from, to) {
            from = Cesium.Cartographic.fromCartesian(from);
            to = Cesium.Cartographic.fromCartesian(to);

            var lat1 = from.latitude;
            var lon1 = from.longitude;
            var lat2 = to.latitude;
            var lon2 = to.longitude;
            var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
            if (angle < 0) {
                angle += Math.PI * 2.0;
            }
            var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度

            angle = angle * degreesPerRadian; //角度
            return angle;
        }
        /*角度*/
        function Angle(p1, p2, p3) {
            var bearing21 = Bearing(p2, p1);
            var bearing23 = Bearing(p2, p3);
            var angle = bearing21 - bearing23;
            if (angle < 0) {
                angle += 360;
            }
            return angle;
        }


        //计算多边形面积
        function getArea(points) {
            var res = 0;
            //拆分三角曲面

            for (var i = 0; i < points.length - 2; i++) {
                var j = (i + 1) % points.length;
                var k = (i + 2) % points.length;
                var totalAngle = Angle(points[i], points[j], points[k]);

                var dis_temp1 = $this.distance(points[j], points[0]);
                var dis_temp2 = $this.distance(points[k], points[0]);
                res += dis_temp1 * dis_temp2 * Math.sin(totalAngle) / 2;
            }

            if (res < 1000000) {
                res = Math.abs(res).toFixed(4) + " 平方米";
            } else {
                res = Math.abs((res / 1000000.0).toFixed(4)) + " 平方公里";
            }

            return res;

        };

        /**
         * 计算多边形的中心（简单的处理）
         * @param mPoints
         * @returns {*[]}
         */
        function getCenterOfGravityPoint(mPoints) {
            var centerPoint = mPoints[0];
            for (var i = 1; i < mPoints.length; i++) {
                centerPoint = Cesium.Cartesian3.midpoint(centerPoint, mPoints[i], new Cesium.Cartesian3());
            }
            return centerPoint;
        }

    }

    /**
     * 画三角量测
     * @param {*} options
     */
    drawTrianglesMeasureGraphics(options = {}) {
        if (this._viewer && options) {
            console.log(222);
            this.destroy()
            var label = options.label
            var positions = [],
                _lineEntity = new Cesium.Entity(),
                $this = this,
                lineObj
            // _handlers = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
            this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)
            // left
            this.handler.setInputAction(function (movement) {

                var cartesian = $this.getCatesian3FromPX(movement.position);
                if (cartesian && cartesian.x) {
                    if (positions.length < 2) {
                        positions.push(cartesian.clone());
                        $this.addPoint(cartesian)
                    }

                    if (positions.length == 2) {

                        let p1 = positions[0];
                        let p2 = positions[1];
                        let cartographic1 = Cesium.Cartographic.fromCartesian(p1);
                        let height1 = cartographic1.height;
                        let cartographic2 = Cesium.Cartographic.fromCartesian(p2);
                        let height2 = cartographic2.height;
                        let s = height1 - height2
                        console.log(s);
                        _addInfoPoint(p2, s)
                        $this.destroy();
                        positions.pop() // 最后一个点无效
                        let cartesian = $this.getCatesian3FromPX(movement.position);
                        // _addInfoPoint(cartesian);
                        console.log($this.transformCartesianArrayToWGS84Array(positions), lineObj);
                        if (typeof options.callback === 'function') {

                            options.callback($this.transformCartesianArrayToWGS84Array(positions), lineObj);
                        }
                        $this.label.style.display = "none"
                    }
                    // 添加量测信息点

                    positions.push(cartesian);
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            this.handler.setInputAction(function (movement) {
                $this.label.style.display = 'block'
                $this.label.innerHTML = '左键点击添加点，再次左键点击结束测量'
                $this.label.style.left = movement.endPosition.x + 10 + 'px'
                $this.label.style.top = movement.endPosition.y + 15 + 'px'
                var cartesian = $this.getCatesian3FromPX(movement.endPosition);
                if (positions.length >= 2) {
                    if (cartesian && cartesian.x) {

                        positions.pop();
                        positions.push(cartesian);
                    }
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);


            this.Straight(positions)


            lineObj = $this.addDataSource.entities.add(_lineEntity);

            //添加坐标点
            function _addInfoPoint(position, s) {

                var _labelEntity = new Cesium.Entity();
                _labelEntity.position = position;
                _labelEntity.point = {
                    pixelSize: 10,
                    outlineColor: Cesium.Color.BLUE,
                    outlineWidth: 5,
                    clampToGround: true,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                };
                _labelEntity.monitoItems = false
                _labelEntity.label = {
                    text: '高度差' + s + '米',
                    show: true,
                    showBackground: true,
                    font: '14px monospace',
                    horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    pixelOffset: new Cesium.Cartesian2(-10, -10), //left top
                    clampToGround: true,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                };
                $this.addDataSource.entities.add(_labelEntity);
            }
        }
    }
    /**
     * 角度测量
     */
    drawAngleMeasyre(options = {}) {
        if (this._viewer && options) {
            var positions = [],
                _lineEntity = new Cesium.Entity(),
                $this = this,
                lineObj,
                _handlers = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);
            // left
            _handlers.setInputAction(function (movement) {
                var cartesian = $this.getCatesian3FromPX(movement.position);
                if (cartesian && cartesian.x) {
                    if (positions.length == 0) {
                        positions.push(cartesian.clone());
                        // 添加量测信息点
                        _addInfoPoint(cartesian);
                        positions.push(cartesian);
                    }
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            _handlers.setInputAction(function (movement) {
                var cartesian = $this.getCatesian3FromPX(movement.endPosition);
                if (positions.length > 0) {
                    if (cartesian && cartesian.x) {
                        positions.pop();
                        positions.push(cartesian);
                    }
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
            // right
            _handlers.setInputAction(function (movement) {
                _handlers.destroy();
                _handlers = null;

                let cartesian = $this.getCatesian3FromPX(movement.position);
                if (cartesian && cartesian.x) {
                    positions.pop();
                    positions.push(cartesian);
                }
                _addInfoPoint(cartesian);

                if (typeof options.callback === 'function') {
                    options.callback($this.transformCartesianArrayToWGS84Array(positions), lineObj);
                }
            }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

            _lineEntity.polyline = {
                width: options.width || 5,
                material: options.material || Cesium.Color.BLUE.withAlpha(0.8),
                clampToGround: false,
            };
            _lineEntity.polyline.positions = new Cesium.CallbackProperty(function () {
                return positions;
            }, false);

            lineObj = $this.addDataSource.entities.add(_lineEntity);

            //添加坐标点
            function _addInfoPoint(position) {
                var _labelEntity = new Cesium.Entity();
                if (positions.length > 1) {
                    var vector = Cesium.Cartesian3.subtract(
                        positions[0],
                        positions[1],
                        new Cesium.Cartesian3(),
                    );

                    // 计算角度
                    var angle = Cesium.Cartesian3.angleBetween(vector, new Cesium.Cartesian3(1, 0, 0)); // 使用 (1, 0, 0) 向量计算角度
                    var angleDegrees = Cesium.Math.toDegrees(angle);
                    _labelEntity.position = position;
                    _labelEntity.point = {
                        pixelSize: 10,
                        outlineColor: Cesium.Color.BLUE,
                        outlineWidth: 5,
                    };
                    _labelEntity.monitoItems = false
                    _labelEntity.label = {
                        text: '角度' + angleDegrees.toFixed(4) + '°',
                        show: true,
                        showBackground: true,
                        font: '14px monospace',
                        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
                        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                        pixelOffset: new Cesium.Cartesian2(-10, -10), //left top
                    };
                    $this.addDataSource.entities.add(_labelEntity);
                } else {
                    var _labelEntity = new Cesium.Entity();
                    _labelEntity.position = position;
                    _labelEntity.point = {
                        pixelSize: 10,
                        outlineColor: Cesium.Color.BLUE,
                        outlineWidth: 5,
                    };
                    _labelEntity.monitoItems = false

                    $tthis.addDataSource.entities.add(_labelEntity);
                }
            }
        }
    }
    createPoint(cartesian) {
        var $this = this
        var point = this.addDataSource.entities.add({
            position: cartesian,
            point: {
                pixelSize: 10,
                color: Cesium.Color.YELLOW,
                clampToGround: true,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
            }
        })
        return point
    }
    // 测量角度
    anglesFn() {
        var activeShapePoints = [] // 选中的点
        var activeShape
        var floatingPoint // 开始点
        // this.handler.destroy()
        this.destroy()
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        var that = this
        this.handler.setInputAction(function (event) {
            var cartesian = that.getCatesian3FromPX(event.position)
            if (Cesium.defined(cartesian)) {
                // 如果我们的鼠标不在地球上，地球位置将无法定义。
                if (activeShapePoints.length === 3) {

                    that.label.style.display = 'none'
                    handlerDestroy()
                }
                if (activeShapePoints.length === 0) {
                    floatingPoint = that.createPoint(cartesian)
                    activeShapePoints.push(cartesian)
                    // activeShape = new PolyLinePrimitive(activeShapePoints)
                    activeShape = that.Straight(activeShapePoints)
                }
                activeShapePoints.push(cartesian)
                that.createPoint(cartesian)
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

        this.handler.setInputAction(function (event) {
            that.label.style.display = 'block'
            that.label.style.left = event.endPosition.x + 10 + 'px'
            that.label.style.top = event.endPosition.y + 15 + 'px'
            var cartesian = that.getCatesian3FromPX(event.endPosition)
            if (Cesium.defined(cartesian)) {
                that.label.innerHTML = '左键添加点，绘制3个点结束'
                if (Cesium.defined(floatingPoint)) {
                    floatingPoint.position.setValue(cartesian)
                    activeShapePoints.pop()
                    activeShapePoints.push(cartesian)
                }
            } else {
                that.label.innerHTML = '超出地球范围'
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        //重新绘制形状，使它不是动态的，并删除动态形状。
        function terminateShape() {
            // drawLine(activeShapePoints)
            // new PolyLinePrimitive(activeShapePoints)
            that.Straight(activeShapePoints)
            that.addDataSource.entities.remove(activeShape)
            floatingPoint = undefined
            activeShape = undefined
        }
        function handlerDestroy() {
            let parentPointEntity = that.addDataSource.entities.add(new Cesium.Entity())
            terminateShape()
            that.addDataSource.entities.add({
                parent: parentPointEntity,
                name: '角度',
                position: activeShapePoints[1],
                label: {
                    text: getAzimuthtAndCenter(activeShapePoints) + '°',
                    font: '16px Helvetica',
                    show: true,
                    fillColor: Cesium.Color.RED,
                    style: Cesium.LabelStyle.FILL, //label样式
                    outlineWidth: 2,
                    verticalOrigin: Cesium.VerticalOrigin.TOP, //垂直位置
                    horizontalOrigin: Cesium.HorizontalOrigin.LEFT, //水平位置
                    // disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    clampToGround: true,
                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                    pixelOffset: new Cesium.Cartesian2(0, 20)
                }
            })
            // that.handler.destroy()
            that.destroy()
            activeShapePoints = []
        }

        function getAzimuthtAndCenter(points) {
            let a = Cesium.Cartesian3.distance(points[0], points[1])
            let b = Cesium.Cartesian3.distance(points[1], points[2])
            let c = Cesium.Cartesian3.distance(points[2], points[0])
            console.log(a)
            console.log(b)
            console.log(c)

            var cosA = (b * b + c * c - a * a) / (2 * b * c)
            var cosB = (a * a + c * c - b * b) / (2 * a * c)
            var cosC = (a * a + b * b - c * c) / (2 * a * b)

            // var A = (Math.acos(cosA) * 180) / Math.PI
            // var B = (Math.acos(cosB) * 180) / Math.PI
            var C = (Math.acos(cosC) * 180) / Math.PI
            return C
        }
    }

    // 剖面分析
    clearBillboard() {
        for (var i = 0; i < this._entities_billboard.length; i++) {
            this.addDataSource.entities.remove(this._entities_billboard[i])
        }
        this._entities_billboard = [] //脏数据
    }

    createBillboard(cartesian) {
        let pinBuilder = new Cesium.PinBuilder()
        var $this = this
        var point = this.addDataSource.entities.add({
            position: cartesian,
            billboard: {
                image: '/imgs/mark-blue.png',
                width: 25, // default: undefined
                height: 25, // default: undefined
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,

            },
        })
        $this._entities_billboard.push(point)
        return point
    }

    ProfileAnalysis(echartsRef, pmShow) {
        var heightList = []
        var $this = this
        // this.handler.destroy()
        this.destroy()
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)

        var $this = this
        var poly = null
        var distance = 0
        this.handler.setInputAction((click) => {
            // const ray = this.viewer.camera.getPickRay(click.position);
            // const cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
            var cartesian = $this.getCatesian3FromPX(click.position)

            if (Cesium.defined(cartesian)) {
                $this.label.style.display = 'block'
                $this.label.innerHTML = '左键添加点，右键结束测量'
                $this.label.style.left = click.position.x + 10 + 'px'
                $this.label.style.top = click.position.y + 15 + 'px'
                const length = this.positions.length
                if (this.positions.length == 0) {
                    this.positions.push(cartesian.clone())
                }
                poly = $this.addLine($this.positions)
                // poly = new PolyLinePrimitive($this.positions)

                this.positions.push(cartesian)
                // distance = getSpaceDistance($this.positions)
                distance = $this.getSpaceDistance($this.positions)
                var textDisance
                textDisance = distance + 'm'
                $this.addDataSource.entities.add({
                    name: '空间直线距离',
                    position: $this.positions[$this.positions.length - 1],
                    point: {
                        pixelSize: 5,
                        color: Cesium.Color.WHITE,
                        outlineColor: Cesium.Color.DEEPSKYBLUE,
                        outlineWidth: 3,
                        // clampToGround: true,
                        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                        // disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    },
                    label: {
                        text: textDisance,
                        font: '18px sans-serif',
                        fillColor: Cesium.Color.DARKORANGE,
                        fillColor: Cesium.Color.RED,
                        pixelOffset: new Cesium.Cartesian2(20, -20),
                        clampToGround: true,
                        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                        // disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    }
                })
                if (length >= 2) {
                    console.log(222);
                    // 插值运算
                    this.interPoints(this.positions, 10, echartsRef, distance)
                }
            }



        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        // this.handler.setInputAction(function (movement) {
        //     $this.label.style.display = 'block'
        //     $this.label.innerHTML = '左键添加点，右键结束测量'
        //     $this.label.style.left = movement.endPosition.x + 10 + 'px'
        //     $this.label.style.top = movement.endPosition.y + 15 + 'px'
        //     var cartesian = $this.getCatesian3FromPX(movement.endPosition);
        //     if ($this.positions.length >= 2) {
        //         if (cartesian && cartesian.x) {

        //             $this.positions.pop();
        //             $this.positions.push(cartesian);
        //         }
        //     }
        // }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        this.handler.setInputAction(function (movement) {
            // $this.handler.destroy() // 关闭事件句柄
            $this.destroy()
            // $this.positions.pop() // 最后一个点无效
            pmShow.value = true
            $this.positions = []

            $this.interData = []
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)

    }

    /**
     * @name: interPoints
     * @Date: 2022-09-27 17:24:02
     * @description: 坐标点插值positionsDegrees
     * @param {any} positions 坐标点数组
     * @param {number} interNumber 取样点个数
     */
    interPoints(positions, interNumber, echartsRef, distance) {

        const posDegrees = [];
        for (let index = 0; index < positions.length; index++) {
            const element = positions[index];
            const ellipsoid = this.viewer.scene.globe.ellipsoid;
            const cartographic = ellipsoid.cartesianToCartographic(element);
            let x = Cesium.Math.toDegrees(cartographic.longitude)
            let y = Cesium.Math.toDegrees(cartographic.latitude)
            let z = cartographic.height
            let data = { longitude: x, latitude: y, height: z }
            posDegrees.push(data);
        }
        let offset, x, y, z;
        for (let i = 0; i < interNumber; ++i) {
            offset = i / (interNumber - 1);
            // 做插值
            x = Cesium.Math.lerp(posDegrees[posDegrees.length - 2].longitude, posDegrees[posDegrees.length - 1].longitude, offset);
            y = Cesium.Math.lerp(posDegrees[posDegrees.length - 2].latitude, posDegrees[posDegrees.length - 1].latitude, offset);
            z = Cesium.Math.lerp(posDegrees[posDegrees.length - 2].height, posDegrees[posDegrees.length - 1].height, offset);

            this.interData.push([x, y, z]);
        }
        //查询地图的地形高度
        const terrainProvider = new Cesium.CesiumTerrainProvider({
            url: 'http://localhost:666/map/dixing'
        })
        let interDataMap = this.interData.map((d) => Cesium.Cartographic.fromDegrees(...d))


        Cesium.sampleTerrainMostDetailed(terrainProvider, interDataMap)
            .then(positions => {
                // console.log(positions);
                const heightList = positions.map(d => {
                    // console.log(d);
                    return {
                        height: d.height,
                        longitude: Cesium.Math.toDegrees(d.longitude),
                        latitude: Cesium.Math.toDegrees(d.latitude)
                    }
                })
                this.initChart(heightList, echartsRef, distance)
            })
    }

    /**
     * @name: initChart
     * @Date: 2022-09-28 09:12:39
     * @description: 生成剖面图
     * @param {any} data 高程数组
     */
    initChart(data, echartsRef, distance) {
        console.log(data);
        console.log(echartsRef);
        console.log(distance);
        var $this = this
        // console.log('生成剖面图');
        this.disposeChart(echartsRef);
        let myChart = echarts.init(echartsRef,);

        var jls = []
        let jl
        for (let i = 0; i <= data.length - 1; i++) {
            if (i == 0) {
                jl = 0
                jls.push(jl)
            } else {
                // jl = ((this.distance / (data.length + 1)) * (i + 2)).toFixed(2)
                jl = (distance / (data.length + 1) * (i + 2)).toFixed(2)
                jls.push(jl)
            }
        }
        // console.log(jls);
        let heights = []
        data.forEach(e => {
            heights.push(e.height)
        })
        // console.log(heights);
        myChart.setOption({

            dataZoom: [
                {
                    type: 'inside',
                    throttle: 500
                }
            ],
            tooltip: {
                show: true
            },
            xAxis: [
                {
                    name: '行程(米)',
                    nameTextStyle: {
                        color: 'rgba(168, 230, 243, 1)',
                        fontSize: 14,
                        padding: [0, 0, 0, -10]
                    },
                    type: 'category',
                    // boundaryGap: !1,
                    axisLine: {
                        show: true
                    },
                    axisLabel: {
                        show: true,
                        textStyle: {
                            color: '#fff',
                        }
                    },
                    data: jls,
                }
            ],
            tooltip: {
                trigger: 'axis',
                formatter: function (params) {
                    console.log(params);
                    console.log(data);
                    let lon = data[params[0].dataIndex].longitude
                    let lat = data[params[0].dataIndex].latitude
                    let alt = data[params[0].dataIndex].height

                    let cartesian = Cesium.Cartesian3.fromDegrees(lon, lat, alt)

                    $this.clearBillboard()
                    $this.createBillboard(cartesian)
                    let str = `当前位置<br>距起点${jls[params[0].dataIndex]}米<br>海拔：${data[params[0].dataIndex].height.toFixed(0)}米<br>经度：${data[params[0].dataIndex].longitude.toFixed(6)}<br>纬度：${data[params[0].dataIndex].latitude.toFixed(6)}`
                    return str
                }
            },

            yAxis: [
                {

                    splitNumber: 10,

                    // z: 3,
                    // max: Math.ceil(heights[heights.length - 1]) + 200,
                    // min: Math.floor(heights[0]) - 200,
                    // interval: Math.ceil(Math.max.apply(null, data) / 5),
                    // max: Math.ceil(Math.max.apply(null, data) / 5) * 5,
                    scale: true,
                    type: 'value',
                    name: '高程(米)',
                    nameTextStyle: {
                        color: 'rgba(168, 230, 243, 1)',
                        fontSize: 14,
                        padding: [0, 0, 10, -40]
                    },
                    axisLabel: {
                        // rotate: 60,
                        // formatter: '{value} 米'
                        textStyle: {
                            color: '#fff',
                        }
                    }
                }
            ],
            series: [
                {
                    name: '高程值',
                    type: 'line',
                    smooth: true,
                    // symbol: 'none',
                    sampling: 'average',
                    symbol: 'circle', //将小圆点改成实心 不写symbol默认空心
                    symbolSize: 6, //小圆点的大小
                    lineStyle: {
                        width: 2,
                        color: '#6AF0FF', //线条颜色
                        // type: "dotted", //'dotted'虚线 'solid'实线
                        shadowColor: '#6AF0FF', //阴影颜色
                        shadowBlur: 5, //阴影的模糊大小。
                        shadowOffsetX: 5, // 阴影水平方向上的偏移距离
                        shadowOffsetY: 5 // 阴影垂直方向上的偏移距离
                    },

                    itemStyle: {
                        normal: {
                            color: 'rgb(255, 70, 131)'
                        }
                    },
                    areaStyle: {
                        normal: {
                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                {
                                    offset: 0,
                                    color: 'rgb(255, 158, 68)'
                                },
                                {
                                    offset: 1,
                                    color: 'rgb(255, 70, 131)'
                                }
                            ])
                        }
                    },
                    data: data.map(e => {
                        return e.height
                    }),
                },

            ]
        })
        window.onresize = () => {
            myChart.resize();
        };
    }

    disposeChart(echartsRef) {
        echarts.dispose(echartsRef);
    }

    // 添加标记
    addMark() {
        this.destroy()
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        var measureFeature_line = []
        // 取消双击事件-追踪该位置
        this.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
        var positions = []
        var poly = null
        var distance = 0
        var cartesian = null
        var floatingPoint
        let that = this
        this.handler.setInputAction(function (movement) {
            that.label.style.display = 'block'
            that.label.style.left = movement.endPosition.x + 10 + 'px'
            that.label.style.top = movement.endPosition.y + 15 + 'px'

            var cartesian = that.getCatesian3FromPX(movement.endPosition)
            if (Cesium.defined(cartesian)) {
                that.label.innerHTML = '左键点击添加标记点，右键点击取消'
            } else {
                that.label.innerHTML = '超出地球范围'
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

        that.handler.setInputAction(movement => {
            var cartesian = that.getCatesian3FromPX(movement.position)
            if (Cesium.defined(cartesian)) {
                that.addDataSource.entities.add({
                    position: cartesian,
                    billboard: {
                        image: '/imgs/mark.png',
                        show: true, // default
                        scale: 2.0, // default: 1.0
                        width: 25, // default: undefined
                        height: 25, // default: undefined
                        // clampToGround: true,
                        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                    },
                    label: {
                        text: '标记点',
                        font: '10px sans-serif',
                        fillColor: Cesium.Color.RED,
                        verticalOrigin: Cesium.VerticalOrigin.CENTER,
                        clampToGround: true,
                        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                        pixelOffset: new Cesium.Cartesian2(24, 20),
                        disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    }
                })
                that.destroy()
                that.label.style.display = 'none'

            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        this.handler.setInputAction(function (movement) {
            that.destroy()
            that.label.style.display = 'none'

        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    // 绘制直线
    addStraightLine(options = {}) {
        if (this._viewer && options) {
            this.destroy()
            var label = options.label
            var positions = [],
                _lineEntity = new Cesium.Entity(),
                $this = this,
                lineObj
            this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)
            this.handler.setInputAction(function (movement) {
                console.log(222);
                var cartesian = $this.getCatesian3FromPX(movement.position);
                if (cartesian && cartesian.x) {
                    if (positions.length == 0) {
                        positions.push(cartesian.clone());
                    }
                    console.log(options);

                    // 添加量测信息点
                    $this.addPoint(cartesian)
                    positions.push(cartesian);
                }
            }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            this.handler.setInputAction(function (movement) {
                $this.label.style.display = 'block'
                $this.label.innerHTML = '左键添加点，右键结束'
                $this.label.style.left = movement.endPosition.x + 10 + 'px'
                $this.label.style.top = movement.endPosition.y + 15 + 'px'
                var cartesian = $this.getCatesian3FromPX(movement.endPosition);
                if (positions.length >= 2) {
                    if (cartesian && cartesian.x) {

                        positions.pop();
                        positions.push(cartesian);
                    }
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
            this.handler.setInputAction(function (movement) {
                $this.destroy();

                positions.pop() // 最后一个点无效
                let cartesian = $this.getCatesian3FromPX(movement.position);
                // _addInfoPoint(cartesian);

                console.log($this.transformCartesianArrayToWGS84Array(positions), lineObj);
                if (typeof options.callback === 'function') {

                    options.callback($this.transformCartesianArrayToWGS84Array(positions), lineObj);
                }
                $this.label.style.display = "none"
                // }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
            }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

            this.Straight(positions)

            lineObj = this.addDataSource.entities.add(_lineEntity);

        }
    }
    // 绘制多边形
    addPolygon(options = {}) {
        var positions = [];
        var clickStatus = false;
        var labelEntity = null;
        var that = this
        this.destroy()

        this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)
        var $this = this
        this.handler.setInputAction((clickEvent) => {
            $this.label.style.display = "block"
            clickStatus = true;
            // var cartesian = that.viewer.scene.globe.pick(that.viewer.camera.getPickRay(clickEvent.position), that.viewer.scene);
            var cartesian = $this.getCatesian3FromPX(clickEvent.position);
            if (!cartesian) {
                return false
            }
            if (positions.length == 0) {
                positions.push(cartesian.clone()); //鼠标左击 添加第1个点
                $this.addPoint(cartesian);
                $this.handler.setInputAction((moveEvent) => {
                    $this.label.style.display = "block"
                    $this.label.style.left = moveEvent.endPosition.x + 10 + 'px'
                    $this.label.style.top = moveEvent.endPosition.y + 15 + 'px'
                    $this.label.innerHTML = '左键添加点，右键结束测量'

                    var movePosition = $this.getCatesian3FromPX(moveEvent.endPosition);
                    if (!movePosition) {
                        return false;
                    }
                    if (positions.length == 1) {
                        positions.push(movePosition);
                        $this.Straight(positions);
                    } else {
                        if (clickStatus) {
                            positions.push(movePosition);
                        } else {
                            positions.pop();
                            positions.push(movePosition);
                        }
                    }
                    if (positions.length >= 3) {
                        // 绘制label
                        if (labelEntity) {
                            this.addDataSource.entities.remove(labelEntity);
                            that.entityCollection.splice(that.entityCollection.indexOf(labelEntity), 1);
                        }
                    }
                    clickStatus = false;
                }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);


            } else if (positions.length == 2) {
                if (!cartesian) {
                    return false
                }
                positions.pop();
                positions.push(cartesian.clone()); // 鼠标左击 添加第2个点

                $this.addPoint(cartesian);

                $this.addPolyGon(positions);

                // 右击结束
                $this.handler.setInputAction((clickEvent) => {

                    var clickPosition = that.viewer.scene.globe.pick(that.viewer.camera.getPickRay(clickEvent.position), that.viewer.scene);
                    if (!clickPosition) {
                        return false;
                    }
                    positions.pop();
                    positions.push(clickPosition);
                    positions.push(positions[0]); // 闭合
                    this.addPoint(clickPosition);

                    $this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
                    $this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
                    $this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
                    $this.label.style.display = "none"
                }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);


            } else if (positions.length >= 3) {
                if (!cartesian) {
                    return false
                }
                positions.pop();
                positions.push(cartesian.clone()); // 鼠标左击 添加第3个点
                $this.addPoint(cartesian);
            }

        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    }

    // 添加集结地
    //加载集结地
    cartesianToLatlng(cartesian) {
        var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian)
        var lat = Cesium.Math.toDegrees(latlng.latitude)
        var lng = Cesium.Math.toDegrees(latlng.longitude)

        return [lng, lat]
    }
    addGather(jjdCallback) {
        function loadGatheringPlace(data, $this) {
            $this.lonLatArr = []
            if (data.length < 2) {
                return null
            }
            var length = data.length
            var p1 = data[0]
            var p2 = data[length - 1]
            var firstPoint = $this.cartesianToLatlng(p1)
            var endPoints = $this.cartesianToLatlng(p2)
            $this.lonLatArr.push(...firstPoint, ...endPoints)
            var gatheringPlace = []
            var res = fineGatheringPlace(firstPoint, endPoints, data, $this)
            for (var i = 0; i < res.length; i++) {
                var cart3 = new Cesium.Cartesian3(res[i].x, res[i].y, res[i].z)
                gatheringPlace.push(cart3)
            }
            var gatheringPlaceEntity = $this.viewer.entities.add({
                polygon: {
                    hierarchy: new Cesium.PolygonHierarchy(gatheringPlace),
                    show: true,
                    fill: true,
                    clampToGround: true,
                    material: Cesium.Color.AQUA.withAlpha(0.5)
                }
            })
            return gatheringPlaceEntity
        }
        //创建集结地
        function createGatheringPlace($this) {
            let s
            var gatheringPlaceEntity = $this.viewer.entities.add({
                polygon: {
                    hierarchy: new Cesium.CallbackProperty(function () {
                        // return new Cesium.PolygonHierarchy($this._positions);
                        var length = $this._positions.length
                        var p1 = $this._positions[0]
                        var p2 = $this._positions[length - 1]
                        var firstPoint = $this.cartesianToLatlng(p1)
                        var endPoints = $this.cartesianToLatlng(p2)
                        var gatheringPlace = []
                        var res = fineGatheringPlace(firstPoint, endPoints, $this._positions, $this)
                        for (var i = 0; i < res.length; i++) {
                            var cart3 = new Cesium.Cartesian3(res[i].x, res[i].y, res[i].z)
                            gatheringPlace.push(cart3)
                        }
                        s = gatheringPlace
                        return new Cesium.PolygonHierarchy(gatheringPlace)
                    }, false),
                    show: true,
                    fill: true,
                    clampToGround: true,
                    material: Cesium.Color.AQUA.withAlpha(0.5)
                }
            })
            $this._entities_gatheringPlace.push(gatheringPlaceEntity)
            return gatheringPlaceEntity
        }

        function cartesianToLatlng(cartesian) {
            var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian)
            var lat = Cesium.Math.toDegrees(latlng.latitude)
            var lng = Cesium.Math.toDegrees(latlng.longitude)

            return [lng, lat]
        }

        //求集结地插值坐标
        function fineGatheringPlace(tailPoint, headerPoint, data, $this) {
            let points = data.length
            if (points < 2) {
                return false
            } else {
                let pnts = new Array()

                data.forEach(function (item) {
                    pnts.push($this.cartesianToLatlng(item))
                })

                if (pnts.length === 2) {
                    let mid = utils.Mid(pnts[0], pnts[1])
                    let d = utils.MathDistance(pnts[0], mid) / 0.9
                    let pnt = utils.getThirdPoint(pnts[0], mid, Constants.HALF_PI, d, true)
                    pnts = [pnts[0], pnt, pnts[1]]
                }
                let mid = utils.Mid(pnts[0], pnts[2])
                pnts.push(mid, pnts[0], pnts[1])

                let [normals, pnt1, pnt2, pnt3, pList] = [[], undefined, undefined, undefined, []]
                for (let i = 0; i < pnts.length - 2; i++) {
                    pnt1 = pnts[i]
                    pnt2 = pnts[i + 1]
                    pnt3 = pnts[i + 2]
                    let normalPoints = utils.getBisectorNormals($this.t, pnt1, pnt2, pnt3)
                    normals = normals.concat(normalPoints)
                }
                let count = normals.length
                normals = [normals[count - 1]].concat(normals.slice(0, count - 1))
                for (let i = 0; i < pnts.length - 2; i++) {
                    pnt1 = pnts[i]
                    pnt2 = pnts[i + 1]
                    pList = pList.concat(pnt1)
                    for (let t = 0; t <= Constants.FITTING_COUNT; t++) {
                        let pnt = utils.getCubicValue(t / Constants.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)

                        pList = pList.concat(pnt)
                    }
                    pList = pList.concat(pnt2)
                }
                return Cesium.Cartesian3.fromDegreesArray(pList)
            }
        }


        var $this = this
        var that = this
        // this.handler.destroy()
        this.destroy()
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
        this.handler.setInputAction(function (evt) {
            //单机开始绘制
            //屏幕坐标转地形上坐标
            var cartesian = $this.getCatesian3FromPX(evt.position)
            if (Cesium.defined(cartesian)) {
                if ($this._positions.length == 0) {
                    $this._positions.push(cartesian.clone())
                    $this.floatingPoint = $this.createPoint(cartesian)
                }
                if ($this._positions.length <= 2) {
                    $this.createPoint(cartesian) // 绘制点
                    $this._positions.push(cartesian)
                }
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        this.handler.setInputAction(function (evt) {
            that.label.style.display = 'block'
            that.label.style.left = evt.endPosition.x + 10 + 'px'
            that.label.style.top = evt.endPosition.y + 15 + 'px'
            var cartesian = $this.getCatesian3FromPX(evt.endPosition)
            if (Cesium.defined(cartesian)) {
                that.label.innerHTML = '左键添加点，右键结束'
                //移动时绘制面
                if ($this._positions.length < 2) return
                var cartesian = $this.getCatesian3FromPX(evt.endPosition)

                if (!Cesium.defined($this._gatheringPlace)) {
                    $this._gatheringPlace = createGatheringPlace($this)

                }
                $this.floatingPoint.position.setValue(cartesian)
                if ($this._gatheringPlace) {
                    $this._positions.pop()
                    $this._positions.push(cartesian)
                }
            } else {
                that.label.innerHTML = '超出地球范围'
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

        this.handler.setInputAction(function (evt) {
            // debugger
            if (!$this._gatheringPlace) return
            var cartesian = $this.getCatesian3FromPX(evt.position)
            $this._positions.pop()
            $this._positions.push(cartesian)
            $this._gatheringPlaceData = $this._positions.concat()
            $this.viewer.entities.remove($this._gatheringPlace) //移除

            var gatheringPlace = loadGatheringPlace($this._gatheringPlaceData, $this) //加载

            let arr = []

            let polyPositions = gatheringPlace.polygon.hierarchy.getValue(
                Cesium.JulianDate.now()
            ).positions;
            let positions = gatheringPlace.polygon.hierarchy._value.positions;
            // 世界坐标转换为弧度
            let ellipsoid = $this.viewer.scene.globe.ellipsoid;
            positions.forEach((v) => {
                let cartographic = ellipsoid.cartesianToCartographic(v);
                // 弧度转换为经纬度
                let lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4); // 经度
                let lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4); // 纬度
                let alt = cartographic.height; // 高度
                arr.push([Number(lon), Number(lat)]);
            });

            console.log(arr.flat());

            if (jjdCallback) {
                jjdCallback(arr.flat())
            }





            $this._gatheringPlace = null
            $this._positions = []
            $this.floatingPoint.position.setValue(cartesian)
            $this._entities_gatheringPlace.push(gatheringPlace)
            $this._gatheringPlaceLast = gatheringPlace
            // $this.clearPoint();
            $this.destroy()
            // $this.getData()
            $this.label.style.display = 'none'

            // $this.callBack($this.lonLatArr)
            // return  $this.getData()
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    }
    //清空实体对象
    clear() {
        // for (var i = 0; i < this._entities_point.length; i++) {
        //     this.viewer.entities.remove(this._entities_point[i])
        // }
        // for (var i = 0; i < this._entities_straightArrow.length; i++) {
        //     this.viewer.entities.remove(this._entities_straightArrow[i])
        // }

        // this.floatingPoint = null //标识点
        // this._straightArrow = null //活动箭头
        // this._straightArrowLast = null //最后一个箭头
        // this._positions = [] //活动点
        // this._entities_point = [] //脏数据
        // this._entities_straightArrow = [] //脏数据
        // this._straightArrowData = null //用于构造箭头数据
    }

    // 直线箭头
    zxjt(zxjtArr, zxjtCallback) {
        this.destroy()
        this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)

        var $this = this
        var zxjtObj = {}
        console.log(zxjtArr);
        var endPoint
        var startPoint
        let id = new Date().getTime()
        this.handler.setInputAction(function (evt) { //单机开始绘制
            var ray = $this.viewer.camera.getPickRay(evt.position);
            console.log($this.positions);
            $this.arrowEntity = null

            if (!ray) return;
            console.log(22);
            var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
            if ($this.positions.length == 0) {

                startPoint = $this.creatPoint(cartesian);
                startPoint.objId = id
                startPoint.type = "firstPoint";
                $this.positions.push(cartesian);
                $this.positions.push(cartesian.clone());
                zxjtObj.id = id
                zxjtObj.startPoint = startPoint
            }
            if ($this.positions.length == 3) {
                endPoint = $this.creatPoint(cartesian);
                endPoint.objId = id
                endPoint.type = "endPoint";
                zxjtArr.push(zxjtObj)
                $this.positions = []
                $this.destroy()
                zxjtObj.endPoint = endPoint
                endPoint.show = false
                startPoint.show = false
                zxjtCallback(zxjtArr)
            }
            // 
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        this.handler.setInputAction(function (evt) { //移动时绘制面

            if ($this.positions.length < 1) return;
            var ray = $this.viewer.camera.getPickRay(evt.endPosition);
            if (!ray) return;
            var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);

            // $this.floatPoint.position.setValue(cartesian);
            if ($this.positions.length >= 2) {
                if (!Cesium.defined($this.arrowEntity)) {
                    $this.positions.push(cartesian);
                    $this.arrowEntity = $this.showArrowOnMap($this.positions);
                    $this.arrowEntity.objId = id
                    zxjtObj.arrowEntity = $this.arrowEntity

                } else {
                    $this.positions.pop();
                    $this.positions.push(cartesian);
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    }

    creatPoint(cartesian) {
        return this.viewer.entities.add({
            position: cartesian,
            billboard: {
                image: "/imgs/point.png",
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            }
        });
    }

    showArrowOnMap(positions) {
        var $this = this;
        var arr = []
        return $this.viewer.entities.add({
            polygon: new Cesium.PolygonGraphics({
                id: new Date().getTime(),
                hierarchy: new Cesium.CallbackProperty(() => {
                    if (positions.length < 2) {
                        return null;
                    }
                    var p1 = positions[1];
                    var p2 = positions[2];
                    var firstPoint = $this.cartesianToLatlng(p1);
                    var endPoints = $this.cartesianToLatlng(p2);
                    var arrow = [];
                    var res = xp.algorithm.fineArrow([firstPoint[0], firstPoint[1]], [endPoints[0], endPoints[1]]);
                    var index = JSON.stringify(res).indexOf("null");
                    if (index == -1) arrow = res;
                    return new Cesium.PolygonHierarchy(arrow);
                }, false),
                clampToGround: true,
                show: true,
                fill: true,
                material: Cesium.Color.fromCssColorString('#0000FF').withAlpha(0.5),
            })
        });
    }



    // 绘制圆形
    drawCircle() {
        let centerPoint = null;
        let centerPointEntity = null;  // 用于存储中点实体的引用
        let radius = 10;
        var $this = this
        // viewer.scene.globe.depthTestAgainstTerrain = false;
        let drawingCircle = this.addDataSource.entities.add({

            name: "画圆",
            ellipse: {
                semiMinorAxis: new Cesium.CallbackProperty(() => {
                    return radius;
                }, false),
                semiMajorAxis: new Cesium.CallbackProperty(() => {
                    return radius;
                }, false),
                material: Cesium.Color.BLUE.withAlpha(0.2),
                outline: true,
                outlineColor: Cesium.Color.RED,
                outlineWidth: 2,
                fill: true,  //为true时只显示轮廓线
            }
        });

        this.destroy()

        this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)

        this.handler.setInputAction(event => {
            // var cartesian = $this.getCatesian3FromPX(event.position);
            var cartesian = $this.getCatesian3FromPX(event.position);
            if (centerPointEntity) {

                if (centerPoint !== null && radius > 0) {
                    $this.label.style.display = 'none'
                    $this.destroy(); // 关闭鼠标事件监听，结束绘制
                    let circleCenter = Cesium.Cartographic.fromCartesian(centerPoint);
                    let lng = Cesium.Math.toDegrees(circleCenter.longitude);
                    let lat = Cesium.Math.toDegrees(circleCenter.latitude);

                }
            }
            if (cartesian && centerPoint === null) {


                centerPoint = cartesian;
                drawingCircle.position = centerPoint;

                // 添加中点实体并保存其引用
                centerPointEntity = $this.addDataSource.entities.add({
                    position: cartesian,
                    point: {
                        color: Cesium.Color.RED,
                        pixelSize: 10
                    }
                });

            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        this.handler.setInputAction(event => {
            $this.label.style.display = 'block'
            $this.label.innerHTML = '左键点击添加点，再次左键点击完成绘制，右键点击，取消绘制'
            $this.label.style.left = event.endPosition.x + 10 + 'px'
            $this.label.style.top = event.endPosition.y + 15 + 'px'
            if (centerPoint) {

                let cartesian = $this.getCatesian3FromPX(event.endPosition);
                if (cartesian) {
                    let distance = Cesium.Cartesian3.distance(centerPoint, cartesian);
                    radius = distance;
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        this.handler.setInputAction(() => {
            $this.destroy(); // 关闭鼠标事件监听，结束绘制
            $this.addDataSource.entities.remove(drawingCircle)
            $this.addDataSource.entities.remove(centerPointEntity)
            $this.label.style.display = 'none'
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    }
    //绘制矩形
    drawRectangle() {
        this.destroy()
        this.handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas)
        var $this = this
        let topLeftPoint = null;
        let bottomRightPoint = null;
        var allPoints = []
        let pointNum = 0
        var startPoint
        var endPoint

        let drawingRectangle = this.addDataSource.entities.add({
            name: "画矩形",
            rectangle: {
                coordinates: new Cesium.CallbackProperty(() => {
                    if (topLeftPoint === null || bottomRightPoint === null) {
                        return;
                    }
                    let west = topLeftPoint.longitude;
                    let north = topLeftPoint.latitude;
                    let east = bottomRightPoint.longitude;
                    let south = bottomRightPoint.latitude;
                    return new Cesium.Rectangle(west, south, east, north);
                }, false),
                material: Cesium.Color.BLUE.withAlpha(0.2),
                closeTop: true,
                closeBottom: false
            }
        });



        $this.handler.setInputAction(event => {

            var cartesian = $this.getCatesian3FromPX(event.position);

            if (cartesian) {
                pointNum++
                if (topLeftPoint === null) {
                    topLeftPoint = Cesium.Cartographic.fromCartesian(cartesian);
                }
                console.log(pointNum);
                pointNum == 1 ? startPoint = $this.addDataSource.entities.add({
                    position: cartesian,
                    point: {
                        color: Cesium.Color.RED,
                        pixelSize: 10
                    }
                }) : endPoint = $this.addDataSource.entities.add({
                    position: cartesian,
                    point: {
                        color: Cesium.Color.RED,
                        pixelSize: 10
                    }
                });

                if (pointNum == 2) {
                    if (topLeftPoint !== null && bottomRightPoint !== null) {
                        $this.destroy(); // 关闭鼠标事件监听，结束绘制
                        let west = Cesium.Math.toDegrees(topLeftPoint.longitude);
                        let north = Cesium.Math.toDegrees(topLeftPoint.latitude);
                        let east = Cesium.Math.toDegrees(bottomRightPoint.longitude);
                        let south = Cesium.Math.toDegrees(bottomRightPoint.latitude);
                        allPoints.push({ lng: west, lat: north });
                        allPoints.push({ lng: east, lat: north });
                        allPoints.push({ lng: east, lat: south });
                        allPoints.push({ lng: west, lat: south });
                        allPoints.push(allPoints[0]); // 闭合
                        $this.label.style.display = 'none'
                    }

                }
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        $this.handler.setInputAction(event => {

            $this.label.style.display = 'block'
            $this.label.innerHTML = '左键点击添加点，再次左键点击完成绘制，右键点击，取消绘制'
            $this.label.style.left = event.endPosition.x + 10 + 'px'
            $this.label.style.top = event.endPosition.y + 15 + 'px'
            if (topLeftPoint) {
                bottomRightPoint = Cesium.Cartographic.fromCartesian($this.getCatesian3FromPX(event.endPosition));
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        $this.handler.setInputAction(() => {
            console.log(startPoint);
            $this.addDataSource.entities.remove(startPoint)
            $this.addDataSource.entities.remove(drawingRectangle)
            // $this.addDataSource.entities.remove(startPoint)
            $this.label.style.display = 'none'
            $this.destroy(); // 关闭鼠标事件监听，结束绘制


        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

    }
}
export default MeasureTool;